home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-09-06 | 5.0 KB | 190 lines | [TEXT/MACA] |
- /*
- * file.c - file handling for the game of Tablut.
- */
-
- #include <quickdraw.h>
- #include <window.h>
- #include <dialog.h>
- #include <toolutil.h>
- #include <memory.h>
- #include <pb.h>
- #include <syserr.h>
- #include "progerr.h"
- #include "tablut.h"
-
- #define ALTSAVECHANGE 400 /* "Save changes..." alert ID */
- #define DONTSAVE 3 /* "don't save changes" item */
- #define FILESTRS 130 /* ID for the File I/O strings */
- #define F_SAVE 1 /* the "save doc as..." prompt */
- #define F_NOTITLE 2 /* the name of an untitled file */
-
- /*
- * newgame() - start a new, untitled game.
- */
- newgame()
- {
- GetIndString(gamename, FILESTRS, F_NOTITLE);
- SetWTitle(mywindow, gamename);
- needsname = 1;
- drawwindow(); /* ...to make sure the window is up-to-date */
- setpieces(); winner = NOWIN; seekboard(0); writeboard(); ischanged = 0;
- setsetup(0);
- }
-
- /*
- * maysave() - if necessary, ask if the user wants to save the old game.
- * If desired, save the old game.
- */
- int /* return TRUE if ok, FALSE if the user cancelled */
- maysave()
- {
- short itemhit;
-
- if (!ischanged) return(1);
- ParamText(gamename, (char *) 0, (char *) 0, (char *) 0);
- itemhit = Alert(ALTSAVECHANGE, (ProcPtr) 0);
- ResetAlrtStage();
- if (itemhit == DONTSAVE) return(1);
- if (itemhit != OK) return(0); /* user cancelled */
- return(savegame(0));
- }
-
- /*
- * savegame() - save the current game.
- */
- int /* return TRUE if ok, FALSE if cancelled */
- savegame(saveas)
- int saveas; /* if TRUE, let the user choose a new name */
- {
- char str[80]; /* (pascal) prompt string */
-
- GetIndString(str, FILESTRS, F_SAVE);
- do {
- if (!FileCreate(needsname || saveas, gamename, &gamevnum,
- MYFILE, MYSIGN, str)) {
- return(0);
- }
- SetWTitle(mywindow, gamename);
- } while ((needsname = !writegamefile()));
- return(1);
- }
-
- /*
- * opengame() - open a previously-saved game.
- */
- int /* return TRUE if ok, FALSE if cancelled */
- opengame()
- {
- do {
- if (!FileFetch(gamename, &gamevnum, MYFILE)) return(0);
- SetWTitle(mywindow, gamename);
- } while ((needsname = !readgamefile()));
- }
-
- /*
- * writegamefile() - write the game out to the existing gamefile.
- */
- int /* TRUE = ok, FALSE = aborted. */
- writegamefile()
- {
- OSErr err;
- short fd; /* reference to the open file */
- struct moveblock *blk; /* current chunk to write out */
- long count; /* # of bytes to write */
- short moves; /* # of moves that have been written */
- long len; /* # of bytes in the file */
-
- if ((err = FSOpen(gamename, gamevnum, &fd)) != noErr) {
- diskerr(err); return(0);
- }
- for (moves = 0, blk = &firstblock; moves < nummoves;
- moves += BDPERBLK, blk = blk->nxtblk) {
- count = nummoves - moves;
- if (count > BDPERBLK) count = BDPERBLK;
- count *= BOARDBYTES;
- if ((err = FSWrite(fd, &count, &(blk->bytes[0]))) != noErr) {
- goto clean1;
- }
- }
- if ((err = GetFPos(fd, &len)) != noErr) goto clean1;
- if ((err = SetEOF(fd, len)) != noErr) goto clean1;
- if ((err = FSClose(fd)) != noErr) goto clean2;
- if ((err = FlushVol((char *) 0, gamevnum)) != noErr) {
- diskerr(err); return(0);
- }
- ischanged = 0;
- return(1);
-
- clean1:
- (void) FSClose(fd);
- clean2:
- (void) FlushVol((char *) 0, gamevnum);
- diskerr(err);
- return(0);
- }
-
- /*
- * readgamefile() - read the gamefile.
- * Note: if the reading fails in the middle, readgamefile()
- * does a newgame() to avoid leaving a corrupt game record.
- */
- int /* TRUE = ok, FALSE = aborted. */
- readgamefile()
- {
- OSErr err;
- short fd; /* reference to the open file */
- struct moveblock *blk; /* current chunk to write out */
- long count; /* # of bytes to write */
- short moves; /* # of moves that have been written */
- long total; /* # of moves in the file */
- char *malloc();
-
- if ((err = FSOpen(gamename, gamevnum, &fd)) != noErr) {
- diskerr(err); return(0);
- }
- if ((err = GetEOF(fd, &total)) != noErr) {
- diskerr(err); return(0);
- }
- total /= BOARDBYTES;
- if (total < 1) { /* the file is corrupted */
- progstop(PE_CORRUPT);
- return(0);
- }
- /* the point of no return. The next line wrecks the old game */
- nummoves = total; ischanged = 0;
- for (moves = 0, blk = &firstblock; moves < nummoves;
- moves += BDPERBLK, blk = blk->nxtblk) {
- count = nummoves - moves;
- if (count > BDPERBLK) count = BDPERBLK;
- count *= BOARDBYTES;
- if ((err = FSRead(fd, &count, &(blk->bytes[0]))) != noErr) {
- goto clean1;
- }
- if (moves + BDPERBLK < nummoves) {
- if (!blk->nxtblk) {
- if (!(blk->nxtblk = (struct moveblock *)
- malloc(sizeof(struct moveblock)))) {
- err = memFullErr;
- goto clean1;
- }
- blk->nxtblk->nxtblk = (struct movevblock *) 0;
- }
- }
- }
- (void) FSClose(fd);
- (void) FlushVol((char *) 0, gamevnum);
-
- drawwindow(); /* ...to make sure the screen is up-to-date */
- seekboard(nummoves - 1);
- readboard();
- setsetup(0);
- return(1);
-
- clean1:
- (void) FSClose(fd);
- (void) FlushVol((char *) 0, gamevnum);
- diskerr(err);
- newgame(); /* ...to clean up the botched game record */
- return(0);
- }
-